Skip to content

Conversation

@lcnr
Copy link
Contributor

@lcnr lcnr commented Jun 3, 2025

Hi there, unfortunately your crate depends on a type system bug which we're going to fix in future Rust versions: rust-lang/rust#141352. We've found this crate via a crater run.

The core issue is that there are two ways to prove e.g. dyn ToJs<JsNullable<JsNumber>>: ToJs<_>:

  • the builtin dyn ToJs<T>: ToJs<T> implementation for trait objects
  • the user-written impl<T: ?Sized> ToJs<T> for T where T: UseInJsCode {}
    • proving the nested UseInJsCode also succeeds as UseInJsCode is a super trait of ToJs

We previously always used the builtin implementaiton to constrain _ to JsNullable<JsNumber> in here, but constraining it to dyn ToJs<JsNullable<JsNumber>> would also be valid when considering this where-bound in isolation. We will no longer prefer this builtin implementation going forward, causing this to remain ambiguous.

This causes calls to the wsdom_macros::load_ts macro to fail with ambiguity errors:

error[E0283]: type annotations needed
  --> wsdom-javascript/src/lib.rs:13:1
   |
13 | wsdom_macros::load_ts!("es5-handpicked.d.ts");
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
   |
   = note: cannot satisfy `dyn ToJs<wsdom_core::js_types::JsNullable<wsdom_core::js_types::JsNumber>>: ToJs<_>`
   = help: the following types implement trait `ToJs<JsType>`

From what I can tell this happens in

pub fn #function_name_ident #function_generics (browser: &__wsdom_load_ts_macro::Browser, #(#arg_names_sig: #arg_types,)*) -> #ret {
__wsdom_load_ts_macro::JsCast::unchecked_from_js(
browser.call_function(#function, [
#( __wsdom_load_ts_macro::UpcastWorkaround::new(#arg_names_body).cast(), )*
], #last_arg_variadic)
)
}

impl<'a, T: ToJs<JsType> + ?Sized, JsType> UpcastWorkaround<'a, T, JsType> {
pub fn new(ty: &'a T) -> Self {

While the builtin impl does not work to create an UpcastWorkaround as constraining JsType to dyn ToJs<JsNullable<JsNumber>> results in a dyn ToJs<JsNullable<JsNumber>>: Sized bound which does not hold, this information does not get considered when checking dyn ToJs<JsNullable<JsNumber>>: ToJs<_> by itself.

I am unsure whether this is the best way to fix the breakage, but from what I can tell there are no unsized types which implement UseInJsCode 🤔

@wishawa
Copy link
Owner

wishawa commented Jun 4, 2025

Thank you for the detailed explanation! I put the ?Sized there intending to have ToJs<[T]>, but then didn't implement that for some reason I can no longer remember 😅. I'll go dig through my code and notes later, but for now let's just merge your change. If we really need ToJs<[T]> later on I suppose some kind of wrapper can be added; ToJs<JsArray<T>> would make more sense from the JavaScript side anyway.

Thank you for working on Rust!!

@wishawa wishawa merged commit b3b3ed6 into wishawa:main Jun 4, 2025
@wishawa
Copy link
Owner

wishawa commented Jun 4, 2025

Looks like the crate that was caught by crater (px-wsdom-javascript) is actually from the fork https://github.com/portal-co/wsdom. @gkgoat1 pinging you here so you are aware of the change.

gkgoat1 added a commit to portal-co/wsdom that referenced this pull request Jun 4, 2025
@gkgoat1
Copy link

gkgoat1 commented Jun 4, 2025

Looks like the crate that was caught by crater (px-wsdom-javascript) is actually from the fork https://github.com/portal-co/wsdom. @gkgoat1 pinging you here so you are aware of the change.

Ported in fork version 0.0.6. Publishing now

@lcnr lcnr deleted the fix-incomplete-inference-guidance branch June 5, 2025 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants